﻿using System.Windows;
using Microsoft.Phone.Scheduler;
using System.Device.Location;
using System;
using System.Collections;
using System.IO.IsolatedStorage;
using System.IO;
using Microsoft.Phone.Shell;
using ShellUiHelpers;

namespace PositionPeriodic_task
{
    public class ScheduledAgent : ScheduledTaskAgent
    {
        private static volatile bool _classInitialized;

        /// <remarks>
        /// ScheduledAgent constructor, initializes the UnhandledException handler
        /// </remarks>
        public ScheduledAgent()
        {
            if (!_classInitialized)
            {
                _classInitialized = true;
                // Subscribe to the managed exception handler
                Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    Application.Current.UnhandledException += ScheduledAgent_UnhandledException;
                });
            }
        }

        /// Code to execute on Unhandled Exceptions
        private void ScheduledAgent_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                System.Diagnostics.Debugger.Break();
            }
        }

        IsolatedStorageSettings settings;

        public TimeSpan timework
        {
            get
            {
                return GetValueOrDefault<TimeSpan>("timeWork", new TimeSpan());
            }
            set
            {
                if (AddOrUpdateValue("timeWork", value))
                {
                    settings.Save();
                }
            }
        }
        public DateTime time
        {
            get
            {
                return GetValueOrDefault<DateTime>("lasttime", DateTime.Now);
            }
            set
            {
                if (AddOrUpdateValue("lasttime", value))
                {
                    settings.Save();
                }
            }
        }
        // выбранная координата
        public GeoCoordinate Selectedcoordinata
        {
            get
            {
                return GetValueOrDefault<GeoCoordinate>("Selectedcoordinata", new GeoCoordinate(60,30));
            }
            set
            {
                if (AddOrUpdateValue("Selectedcoordinata", value))
                {
                    settings.Save();
                }
            }
        }
        // текущая координата
        public GeoCoordinate Currentcoordinata
        {
            get
            {
                return GetValueOrDefault<GeoCoordinate>("Currentcoordinata", new GeoCoordinate(60, 30));
            }
            set
            {
                if (AddOrUpdateValue("Currentcoordinata", value))
                {
                    settings.Save();
                }
            }
        }
        // время работы за вчера
        public TimeSpan timework_Yesterday
        {
            get
            {
                return GetValueOrDefault<TimeSpan>("timeWork_Yesterday", new TimeSpan());
            }
            set
            {
                if (AddOrUpdateValue("timeWork_Yesterday", value))
                {
                    settings.Save();
                }
            }
        }
        // время работы за неделю
        public TimeSpan timework_lastweek
        {
            get
            {
                return GetValueOrDefault<TimeSpan>("timeWork_lastweek", new TimeSpan());
            }
            set
            {
                if (AddOrUpdateValue("timeWork_lastweek", value))
                {
                    settings.Save();
                }
            }
        }
        // время работы за неделю
        public TimeSpan timework_lastmounth
        {
            get
            {
                return GetValueOrDefault<TimeSpan>("timeWork__lastmounth", new TimeSpan());
            }
            set
            {
                if (AddOrUpdateValue("timeWork__lastmounth", value))
                {
                    settings.Save();
                }
            }
        }

        private GeoPosition<GeoCoordinate> GetCachedLocation()
        {
            GeoCoordinateWatcher geoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
            geoWatcher.Start();
            GeoPosition<GeoCoordinate> position = geoWatcher.Position;
            geoWatcher.Stop();

#if DEBUG
            ShellToast MyToast = new ShellToast();
            MyToast.Title = "pos";

            if (position.Location.IsUnknown != true)
            {
                if (position.Location.Latitude < Selectedcoordinata.Latitude + 0.002 && position.Location.Latitude > Selectedcoordinata.Latitude - 0.002)
                {
                    if (position.Location.Longitude < Selectedcoordinata.Longitude + 0.002 && position.Location.Longitude > Selectedcoordinata.Longitude - 0.002)
                    {
                        // на работе
                        MyToast.Content = "On work";
                    }
                    else
                    {
                        MyToast.Content = "house";
                    }
                }
                else
                {
                    MyToast.Content = "house";
                }
            }
            else
            {
                MyToast.Content = "Unknown latitude and longitude.";
            }

            MyToast.Show();
#endif

            // сохраним полученную координату
            Currentcoordinata = position.Location;

            return position;
        }

        protected override void OnInvoke(ScheduledTask task)
        {
            settings = IsolatedStorageSettings.ApplicationSettings;

            // будем вести журнал времени
            IsolatedStorageFile CoordStorage = IsolatedStorageFile.GetUserStoreForApplication();
            IsolatedStorageFileStream coordinataStream = CoordStorage.OpenFile("journal.txt", System.IO.FileMode.OpenOrCreate);

            GeoCoordinate coord = GetCachedLocation().Location;

            TimeSpan span1 = new TimeSpan(time.Day, time.Hour, time.Minute, time.Second);
            TimeSpan span2 = new TimeSpan(DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);

            if (time.Day != DateTime.Now.Day)
            {   // нaступил новый день
                timework_Yesterday = timework;
                timework = new TimeSpan(0, 0, 0, 0);

                // Занесем в журнал информацию о прошедшем дне
                coordinataStream.Seek(0, SeekOrigin.End);

                coordinataStream.Write(System.Text.Encoding.UTF8.GetBytes(time.ToShortDateString().ToString()), 0, time.ToShortDateString().ToString().Length);
                coordinataStream.Write(System.Text.Encoding.UTF8.GetBytes(" "), 0, 1);
                coordinataStream.Write(System.Text.Encoding.UTF8.GetBytes(timework_Yesterday.ToString()), 0, timework_Yesterday.ToString().Length);
                coordinataStream.Write(System.Text.Encoding.UTF8.GetBytes("\n"), 0, 1);

                coordinataStream.Close();
            }
            if ((time.DayOfWeek != DateTime.Now.DayOfWeek) && (DateTime.Now.DayOfWeek == DayOfWeek.Monday))
            {   // нaступил новая неделя
                timework_lastweek = new TimeSpan(0, 0, 0, 0);
            }
            if (time.Month != DateTime.Now.Month)
            {   // нaступил новый месяц
                timework_lastmounth = new TimeSpan(0, 0, 0, 0);
            }

            // запомним текущее время
            time = DateTime.Now;

            bool OnWork = false;

            // Посмотрим мы рядом с работой?
            if (coord.Latitude < Selectedcoordinata.Latitude + 0.0025 && coord.Latitude > Selectedcoordinata.Latitude - 0.0025)
            {
                if (coord.Longitude < Selectedcoordinata.Longitude + 0.0025 && coord.Longitude > Selectedcoordinata.Longitude - 0.0025)
                {
                    // на работе
                    timework += (span2 - span1);
                    timework_lastweek += (span2 - span1);
                    timework_lastmounth += (span2 - span1);

                    OnWork = true;
                }
            }

            {   //Тайл изменим
                string work;
                string work_time;

                if (OnWork == true)
                {
                    work = "на работе";
                    work_time = timework.ToString();
                }
                else
                {
                    work = "ушел";
                    work_time = "с работы";
                }

                TileHelper.UpdateTile(new ExtendedTileData
                {
                    FrontText  = work,
                    FrontTitle = work_time,
                    BackText = null,
                    BackTitle = null,
                }, OnWork, (int)timework.TotalSeconds);
            }

#if DEBUG
            ScheduledActionService.LaunchForTest(task.Name, System.TimeSpan.FromSeconds(10));
#endif
            NotifyComplete();
        }

        // сохранение параметров
        public bool AddOrUpdateValue(string Key, Object value)
        {
            bool valueChanged = false;

            // If the key exists
            if (settings.Contains(Key))
            {
                // If the value has changed
                if (settings[Key] != value)
                {
                    // Store the new value
                    settings[Key] = value;
                    valueChanged = true;
                }
            }
            // Otherwise create the key.
            else
            {
                settings.Add(Key, value);
                    valueChanged = true;
            }
            return valueChanged;
        }

        public T GetValueOrDefault<T>(string Key, T defaultValue)
        {
            T value;

            // If the key exists, retrieve the value.
            if (settings.Contains(Key))
            {
                value = (T)settings[Key];
            }
            // Otherwise, use the default value.
            else
            {
                value = defaultValue;
            }
            return value;
        }

    }
}